using Microsoft.AspNetCore.Mvc;
using SG3L_RAG.Application.DTOs;
using SG3L_RAG.Application.Interfaces;
using System.Text;

namespace SG3L_RAG.Api.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class DocumentUploadController : ControllerBase
    {
        private readonly IDocumentProcessingService _documentProcessingService;
        private readonly IDocumentService _documentService;
        private readonly ILogger<DocumentUploadController> _logger;

        public DocumentUploadController(
            IDocumentProcessingService documentProcessingService,
            IDocumentService documentService,
            ILogger<DocumentUploadController> logger)
        {
            _documentProcessingService = documentProcessingService;
            _documentService = documentService;
            _logger = logger;
        }

        /// <summary>
        /// 上传并处理文档
        /// </summary>
        /// <param name="file">文档文件</param>
        /// <param name="title">文档标题</param>
        /// <param name="description">文档描述</param>
        /// <param name="visibility">访问权限</param>
        /// <returns>上传结果</returns>
        [HttpPost("upload")]
        public async Task<ActionResult<object>> UploadDocument(
            IFormFile file,
            [FromForm] string? title = null,
            [FromForm] string? description = null,
            [FromForm] string? visibility = "private")
        {
            try
            {
                _logger.LogInformation("开始处理文档上传请求");
                _logger.LogInformation($"文件: {file?.FileName}, 大小: {file?.Length}, 标题: {title}");

                if (file == null || file.Length == 0)
                {
                    _logger.LogWarning("未提供文件或文件为空");
                    return BadRequest(new { error = "请选择要上传的文件" });
                }

                // 文件大小限制 (50MB)
                const long maxFileSize = 50 * 1024 * 1024;
                if (file.Length > maxFileSize)
                {
                    _logger.LogWarning($"文件大小超出限制: {file.Length} bytes");
                    return BadRequest(new { error = "文件大小不能超过50MB" });
                }

                // 支持的文件类型
                var supportedExtensions = new[] { ".txt", ".md", ".html", ".htm", ".doc", ".docx", ".pdf" };
                var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
                
                if (!supportedExtensions.Contains(fileExtension))
                {
                    _logger.LogWarning($"不支持的文件类型: {fileExtension}");
                    return BadRequest(new { error = $"不支持的文件类型: {fileExtension}。支持的格式: {string.Join(", ", supportedExtensions)}" });
                }

                var userId = GetCurrentUserId();
                _logger.LogInformation($"用户ID: {userId}");

                // 读取文件内容
                byte[] fileContent;
                using (var memoryStream = new MemoryStream())
                {
                    await file.CopyToAsync(memoryStream);
                    fileContent = memoryStream.ToArray();
                }

                // 清理标题和描述中的无效字符
                var cleanTitle = CleanString(title ?? Path.GetFileNameWithoutExtension(file.FileName));
                var cleanDescription = CleanString(description ?? string.Empty);
                var cleanFileName = CleanString(file.FileName);
                var cleanVisibility = visibility ?? "private";

                // 创建上传DTO
                var uploadDto = new DocumentUploadDto
                {
                    Title = cleanTitle,
                    FileName = cleanFileName,
                    ContentType = file.ContentType ?? "application/octet-stream",
                    FileSize = file.Length,
                    FileContent = fileContent,
                    UploaderId = userId,
                    Description = cleanDescription,
                    Permission = cleanVisibility
                };

                // 处理文档
                _logger.LogInformation("开始处理文档");
                var result = await _documentProcessingService.ProcessUploadedFileAsync(uploadDto);

                if (result.IsSuccessful)
                {
                    _logger.LogInformation($"文档处理成功，文档ID: {result.DocumentId}");
                    return Ok(new
                    {
                        success = true,
                        message = "文档上传并处理成功",
                        documentId = result.DocumentId,
                        status = result.Status,
                        totalChunks = result.TotalChunks,
                        processedAt = result.ProcessedAt
                    });
                }
                else
                {
                    _logger.LogWarning($"文档处理失败: {result.ErrorMessage}");
                    return BadRequest(new
                    {
                        success = false,
                        error = result.ErrorMessage,
                        status = result.Status
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "上传文档时发生错误，详细信息: {ExceptionDetails}", new
                {
                    Message = ex.Message,
                    InnerException = ex.InnerException?.Message,
                    StackTrace = ex.StackTrace
                });
                return StatusCode(500, new { 
                    error = "服务器内部错误",
                    details = ex.Message,
                    innerException = ex.InnerException?.Message
                });
            }
        }

        /// <summary>
        /// 获取文档处理状态
        /// </summary>
        /// <param name="documentId">文档ID</param>
        /// <returns>处理状态</returns>
        [HttpGet("{documentId}/status")]
        public async Task<ActionResult<object>> GetProcessingStatus(Guid documentId)
        {
            try
            {
                var document = await _documentService.GetByIdAsync(documentId);
                if (document == null)
                {
                    return NotFound(new { error = "文档不存在" });
                }

                // 获取处理详情
                var processedDocuments = await _documentProcessingService.GetProcessedDocumentsAsync();
                var documentInfo = processedDocuments.FirstOrDefault(d => d.Id == documentId);

                if (documentInfo == null)
                {
                    return Ok(new
                    {
                        documentId = documentId,
                        status = "未处理",
                        isProcessed = false
                    });
                }

                return Ok(new
                {
                    documentId = documentInfo.Id,
                    title = documentInfo.Title,
                    status = documentInfo.Status,
                    isProcessed = documentInfo.IsProcessed,
                    chunkCount = documentInfo.ChunkCount,
                    fileSize = documentInfo.FileSize,
                    uploadedAt = documentInfo.CreatedAt,
                    updatedAt = documentInfo.UpdatedAt
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取文档处理状态时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 重新处理文档
        /// </summary>
        /// <param name="documentId">文档ID</param>
        /// <returns>处理结果</returns>
        [HttpPost("{documentId}/reprocess")]
        public async Task<ActionResult<object>> ReprocessDocument(Guid documentId)
        {
            try
            {
                var userId = GetCurrentUserId();
                
                // 验证文档是否存在且用户有权限
                var document = await _documentService.GetByIdAsync(documentId);
                if (document == null)
                {
                    return NotFound(new { error = "文档不存在" });
                }

                if (document.UploaderId != userId)
                {
                    return StatusCode(403, "您没有权限重新处理此文档");
                }

                var success = await _documentProcessingService.ReprocessDocumentAsync(documentId);

                if (success)
                {
                    return Ok(new
                    {
                        success = true,
                        message = "文档重新处理已开始",
                        documentId = documentId
                    });
                }
                else
                {
                    return BadRequest(new
                    {
                        success = false,
                        error = "重新处理文档失败"
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重新处理文档时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 获取用户的文档列表
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <returns>文档列表</returns>
        [HttpGet("my-documents")]
        public async Task<ActionResult<object>> GetMyDocuments([FromQuery] int page = 1, [FromQuery] int pageSize = 20)
        {
            try
            {
                var userId = GetCurrentUserId();
                var documents = await _documentProcessingService.GetProcessedDocumentsAsync(userId);

                var totalCount = documents.Count;
                var skip = (page - 1) * pageSize;
                var pagedDocuments = documents.Skip(skip).Take(pageSize).ToList();

                return Ok(new
                {
                    documents = pagedDocuments.Select(d => new
                    {
                        id = d.Id,
                        title = d.Title,
                        fileName = d.FileName,
                        fileType = d.FileType,
                        fileSize = d.FileSize,
                        status = d.Status,
                        isProcessed = d.IsProcessed,
                        chunkCount = d.ChunkCount,
                        uploadedAt = d.CreatedAt,
                        updatedAt = d.UpdatedAt
                    }),
                    pagination = new
                    {
                        page = page,
                        pageSize = pageSize,
                        totalCount = totalCount,
                        totalPages = (int)Math.Ceiling((double)totalCount / pageSize),
                        hasNextPage = totalCount > skip + pageSize,
                        hasPreviousPage = page > 1
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取用户文档列表时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 删除文档
        /// </summary>
        /// <param name="documentId">文档ID</param>
        /// <returns>删除结果</returns>
        [HttpDelete("{documentId}")]
        public async Task<ActionResult<object>> DeleteDocument(Guid documentId)
        {
            try
            {
                var userId = GetCurrentUserId();
                
                var document = await _documentService.GetByIdAsync(documentId);
                if (document == null)
                {
                    return NotFound(new { error = "文档不存在" });
                }

                if (document.UploaderId != userId)
                {
                    return StatusCode(403, "您没有权限删除此文档");
                }

                // 删除文档和相关的分片
                await _documentService.DeleteAsync(documentId);

                return Ok(new
                {
                    success = true,
                    message = "文档删除成功",
                    documentId = documentId
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除文档时发生错误");
                return StatusCode(500, new { error = "服务器内部错误" });
            }
        }

        /// <summary>
        /// 获取当前用户ID
        /// </summary>
        /// <returns>用户ID</returns>
        private Guid GetCurrentUserId()
        {
            // 从请求头获取用户ID
            var userIdHeader = Request.Headers["X-User-Id"].FirstOrDefault();
            if (Guid.TryParse(userIdHeader, out var userId))
            {
                return userId;
            }

            // 返回默认测试用户ID
            return Guid.Parse("00000000-0000-0000-0000-000000000001");
        }

        /// <summary>
        /// 清理字符串中的无效字符
        /// </summary>
        /// <param name="input">输入字符串</param>
        /// <returns>清理后的字符串</returns>
        private static string CleanString(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            // 移除空字节和控制字符
            var cleaned = new StringBuilder();
            foreach (char c in input)
            {
                // 只保留可打印的ASCII字符和常见的Unicode字符
                if (c >= 32 && c <= 126) // 基本ASCII可打印字符
                {
                    cleaned.Append(c);
                }
                else if (c > 126 && !char.IsControl(c)) // Unicode字符但不是控制字符
                {
                    cleaned.Append(c);
                }
                else if (c == '\n' || c == '\r' || c == '\t') // 保留常见的空白字符
                {
                    cleaned.Append(' ');
                }
                else
                {
                    // 其他字符替换为空格
                    cleaned.Append(' ');
                }
            }
            
            // 清理多余的空格并去除首尾空白
            var result = System.Text.RegularExpressions.Regex.Replace(cleaned.ToString(), @"\s+", " ").Trim();
            return string.IsNullOrEmpty(result) ? "untitled" : result;
        }
    }
}
